home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-19
/
surfsrc3.zip
/
SURFGRAF.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1991-11-09
|
34KB
|
1,155 lines
{$I defines.inc}
Unit SURFGRAF;
{Graphics primitives for Surfmodl. These primitives use the borland .BGI }
{routines. If you add support for a new graphics system, you must update }
{the SYS_NAME, LGLSYS, MAXSYS, and perhaps OLDSYS routines. You also must}
{update the SURFBGI bgi emulation routines}
INTERFACE
uses dos, crt,
SHAREDEC,
{$IFDEF EXTERNAL}
SURFbgi;
{$ELSE}
Graph;
{$ENDIF}
{$IFDEF USE8087}
type real = single;
{$ENDIF}
{ Names of all the systems currently supported by SURFMODL: }
const VGA256 = 6; { shared with IBM8514 }
MAXSYS = 11; { maximum # of systems currently supported }
const Sys_name: array[1..MAXSYS] of string[30] = (
'IBM Color Graphics Adapter',
'IBM MCGA Graphics Adapter',
'IBM Enhanced Graphics Adapter',
'IBM EGA with 64K memory',
'IBM EGA with Mono Display',
'VGA With 256-Color Capability',
'Hercules Mono Graphics Adapter',
'AT&T 6300 400 line mode',
'IBM VGA Graphics Adapter',
'IBM 3270',
{$IFDEF VAXMATE }
'DEC Vaxmate'
{$IFDEF USE_IFF}
ERROR - YOU CAN NOT DEFINE BOTH VAXMATE AND USE_IFF
{$ENDIF}
{$ELSE}
{$IFDEF USE_IFF}
'AMIGA IFF'
{$ELSE}
'RESERVED' {<<<<<< Note, this must be present and in CAPS to work}
{$ENDIF}
{$ENDIF}
);
const RESERVED = 11; { TP 5.0 & above no longer have a RESERVED type }
LGLSYS: array[1..MAXSYS] of integer = (
CGA,
MCGA,
EGA,
EGA64,
EGAMONO,
VGA256,
HERCMONO,
ATT400,
VGA,
PC3270,
{$IFDEF VAXMATE} {Make unused systems RESERVED}
VM400
{$ELSE}
{$IFDEF USE_IFF}
IFF
{$ELSE}
RESERVED
{$ENDIF}
{$ENDIF}
);
{table to convert old Surfmodl 1.x system number to new}
const oldsys :array[1..10] of integer = (
CGA, { CGA : old number 1}
EGA, { EGA : old number 2}
HERCMono, { HERCMono : old number 3}
detect, { Sanyo Unsupported, try to detect}
detect, { Heath/Zenith Z-100 Unsupported, try to detect }
CGA, { Toolbox CGA, old number 6 }
ATT400, { AT&T 6300 mode, old number 7 }
PC3270, { IBM 3270, old number 8 }
EGA64, { Old QUADEGA (640x480), closest is (640x350) }
EGA64); { Old QUADEGA (752x410), closest is (640x350) }
var
driveron : boolean; { flag for if driver is on or not }
grsys : integer; { Graphics system being used }
grmode : integer; { Graphics mode in the system }
dorandom : boolean; { flag for random interpolation }
RandShade : real; { Random shade pattern }
Ngraphchar: integer; { #chars across graphics screen}
{ If 0 then no text will be
displayed on the graphics screen }
Gxmin, Gxmax,
Gymin, Gymax: integer; { graphics screen limits }
ncolors : integer; { Number of colours supported in current mode}
MONO : boolean; { Flag for monochrome graphics }
Viewchanged : boolean; { Flag for changed viewpoint }
Flpurpose : string[127]; { title for plot }
BGIDIR : string; { directory for BGI files }
Textcol : integer; { color to display text on text screen }
BGcol : integer; { background color for text display }
Graphcol : integer; { color to display text on graphics screen }
RevVideo : boolean; { reverse video? }
ShowTitle : boolean; { display title on plot? }
{$ifdef DEBUG}
Dbgfile : text; { debugging file }
{$endif}
{ NEW VARIABLES FOR THE FULL-PALETTE MATERIAL DEFINITION: }
const MAXSHADES = 32; { maximum # of shades to be plotted per matl }
{$IFDEF USE_IFF}
RESERVED_COLORS = 2; { # of reserved colors on Amiga }
{$ELSE}
RESERVED_COLORS = 16; { # of reserved colors in VGA 256-color mode }
{$ENDIF}
type matlarray = array[1..MAXMATL] of integer;
var
RGB_levels: integer; { assigned for each device - max #
distinguishable levels in EACH of the red,
green & blue components (= 63 on VGA, 255 on Amiga)
NOTE the Amiga really only has 15 RGB levels, but
for IFF format all values are 0..255.
}
Maxcol_mat: integer; { max # colors used in palette for each matl }
Ncol_mat: matlarray; { actual # colors used by each matl }
{ The following set of variables is only used by devices with a large
color palette (like the VGA and Amiga). The new data file format
permits specification of an RGB value for each material. This value is
specified as an integer in the range from 0..255 with 255 corresponding
to full intensity. Even though none of the currently-supported devices
in SURFMODL have a color range this large, this is always the range used
in the data file. Internally, this number is scaled to the proper range
for the device you are using (0..63 for the VGA and 0..15 for the Amiga).
If an old data file format is used (and therefore the RGB values
are not entered), then the full palette of the devices is still supported
by automatically using a table of RGB values for the standard colors of
the PC. Note that you can also specify RGB levels through the Lighting
Menu. Also note that these RGB numbers are ignored if you are using a
device other than the VGA or Amiga, and the old color #'s are used.
}
VGApal: SurfPalette; { The full VGA palette }
procedure gplot (x,y,color:integer);
procedure exgraphic;
procedure closedriver; {shuts down entire graphics system }
procedure GDRAW (X1t, Y1t, X2t, Y2t, Color: integer);
procedure GHDRAW (X1, X2, Y, Color: integer);
procedure SHPLOT (X, Y, Color: integer; Fmod: integer);
procedure SHDRAW (X1, X2, Y, Color: integer; Fmod: integer);
procedure SETSYS;
procedure SELECT_SYS;
procedure SETGMODE (Nmatl: integer);
procedure stopstat;
function grafstat : boolean;
function checkey : boolean;
procedure puttext (X, Y: integer; textstring: string; color: integer);
function width_of_text (textstring: string): integer;
function height_of_text (textstring: string): integer;
function savescrn (filename : string) : boolean;
(* KVC Removed:
function readscrn (filename : string; var grsys,grmode : integer;
var image : picbuf; var nbuf : integer; var nlines_buf : nlpic;
var vgapalette : SurfPalette; oldgrsys, oldgrmode : integer) : boolean;
*)
procedure VGASetAllPalette (var P : SurfPalette);
procedure Abort(Msg : string);
function DetectVGA256 : integer;
procedure def_palette (Nmatl: integer);
procedure findcolors (Mat, Matcolor: integer; var Shade: real; var Color1, Color2:
integer);
procedure color_to_rgb (Color: integer; var Red, Grn, Blu: integer);
IMPLEMENTATION
{$I PALETTE.INC}
procedure gplot (x,y,color:integer);
{plot one dot in given colour, with clipping}
begin
putpixel (x,y,color);
end;
procedure EXGRAPHIC;
{ Exit graphics mode }
begin
RestoreCrtMode;
end; { procedure EXGRAPHIC }
procedure closedriver;
{ closes down the existing graphics system }
begin
if driveron then begin
setgraphmode(grmode);
closegraph;
driveron := false;
end;
end;
{ NOTE: This file contains several routines, which are the system-independent
graphics primitives of SURFMODL:
GDRAW - Line drawing routine
GHDRAW - Horizontal line drawing routine
SHPLOT - Shaded pixel plot routine
SHDRAW - Shaded line drawing routine
DITHPLOT - Dithered pixel plot routine
DITHDRAW - Dithered line drawing routine
INTRPLOT - Interpolated pixel plot routine
INTRDRAW - Interpolated line drawing routine
}
procedure GDRAW (X1t, Y1t, X2t, Y2t, Color: integer);
{ This routine was written by Russell Nelson, to draw a line using the
GPLOT primitive -- for systems that do not provide a line drawing
primitive. This routine does NOT clip. }
var
delta_x, delta_y : integer;
inc_x, inc_y : integer;
epsilon, count : integer;
x1, y1, x2, y2: integer;
begin
if (x2t < x1t) then begin
{ Make sure the lines are always plotted in the same direction, for
smooth line drawing in hidden line removal. }
x1 := x2t;
y1 := y2t;
x2 := x1t;
y2 := y1t;
end else begin
x1 := x1t;
y1 := y1t;
x2 := x2t;
y2 := y2t;
end;
delta_x := abs(x2 - x1);
delta_y := abs(y2 - y1);
{ if x2 > x1 then inc_x := 1 else inc_x := -1; }
inc_x := 1;
if y2 > y1 then inc_y := 1 else inc_y := -1;
if delta_x > delta_y then begin
count := delta_x + 1;
epsilon := delta_x div 2;
while count>0 do begin
GPLOT(x1, y1, Color);
epsilon := epsilon + delta_y;
if epsilon > delta_x then begin
epsilon := epsilon - delta_x;
y1 := y1 + inc_y;
end;
x1 := x1 + inc_x;
count := count - 1;
end;
end else begin
count := delta_y + 1;
epsilon := delta_y div 2;
while count>0 do begin
GPLOT(x1, y1, Color);
epsilon := epsilon + delta_x;
if epsilon > delta_y then begin
epsilon := epsilon - delta_y;
x1 := x1 + inc_x;
end;
y1 := y1 + inc_y;
count := count - 1;
end;
end;
end; { procedure GDRAW }
{ GHDRAW: Horizontal line draw.}
procedure GHDRAW (X1, X2, Y, Color: integer);
begin
gdraw (x1,y,x2,y,color);
end; { procedure GHDRAW }
procedure SHPLOT (X, Y, Color: integer; Fmod: integer);
{ system-independent shaded pixel plot command }
{ This routine uses the system's colors as shades of grey }
begin
if (Fmod > 1) then begin
if (X mod Fmod = Y mod Fmod) then
gplot (X, Y, Color)
else
gplot (X, Y, 0);
end else if (Fmod < -1) then begin
if (X mod -Fmod = Y mod -Fmod) then
gplot (X, Y, 0)
else
gplot (X, Y, Color);
end else
gplot (X, Y, Color);
end; { procedure SHPLOT }
procedure SHDRAW (X1, X2, Y, Color: integer; Fmod: integer);
{ system-independent shaded horizontal line drawing command }
{ This routine uses the system's colors as shades of grey }
var X: integer; { x coord }
begin
if (abs(Fmod) < 2) then
ghdraw (X1, X2, Y, Color)
else if (Fmod > 1) then begin
for X := X1 to X2 do
if (X mod Fmod = Y mod Fmod) then
gplot (X, Y, Color)
else
gplot (X, Y, 0);
end else begin
for X := X1 to X2 do
if (X mod -Fmod = Y mod -Fmod) then
gplot (X, Y, 0)
else
gplot (X, Y, Color);
end;
end; { procedure SHDRAW }
{ PUTTEXT puts a text message on the graphics screen }
procedure puttext (X, Y: integer; textstring: string; color: integer);
begin
setcolor (color);
outtextxy (x, y, textstring);
end; { procedure PUTTEXT }
{ WIDTH_OF_TEXT returns the width of a text string in pixels }
function width_of_text (textstring: string): integer;
begin
width_of_text := textwidth (textstring);
end; { function WIDTH_OF_TEXT }
{ HEIGHT_OF_TEXT returns the height of a text string in pixels }
function height_of_text (textstring: string): integer;
begin
height_of_text := textheight (textstring);
end; { function HEIGHT_OF_TEXT }
procedure SETSYS;
{ Initialize system-dependent parameters }
var grtmp: integer;
grmtmp: integer;
success : boolean;
begin
{$IFDEF USE_IFF}
{ Have to use the IFF driver if compiled for it. }
if grsys <> IFF then begin
writeln('ERROR: GRSYS must be ', IFF, ' in SURFIFF.CFG');
halt;
end;
{$ENDIF}
success := true;
{$IFNDEF EXTERNAL}
{ KVC 04/20/91 Make Turbo recognize the SVGA256.BGI file }
grtmp := InstallUserDriver('SVGA256', @DetectVGA256);
{$ENDIF}
{ KVC 09/11/91 This call to detect shouldn't be necessary, but otherwise
Turbo does not seem to be using the SVGA256.BGI file.
}
grtmp := detect;
grmtmp := 0;
if (grsys <> VGA256) then
grtmp := grsys;
initgraph (grtmp,grmtmp,BGIDIR);
if (graphresult < 0) then
success := false
else begin
{ Have to go into graphics mode to read the parameters: }
setgraphmode(grmode);
if (graphresult < 0) then
success := false
else begin
ngraphchar := GetMaxX div textwidth ('Z');
GXmin := 0;
GXMax := GetMaxX ;
Gymin := 0;
GYMax := GetMaxY;
Ncolors := GetMaxColor;
viewchanged := true;
driveron := true;
restorecrtmode;
if (graphresult < 0) then
success := false;
end;
end;
if (not success) then begin
writeln (grapherrormsg(grsys));
writeln;
writeln ('If the .BGI files are not in the current directory');
writeln ('then you can use SET to set an environment variable');
writeln ('called BGIDIR which points to the .BGI file directory.');
writeln;
writeln ('SurfModl Halted');
halt(1);
end;
end; { procedure SETSYS }
procedure SELECT_SYS;
{ Allow the user to select a system & mode. This routine is only used
in installation now.
}
var
sys : integer;
message : string;
modelow,modehi : integer;
num : integer;
code : integer;
begin
{$IFNDEF EXTERNAL}
{ KVC 04/20/91 Make Turbo recognize the VGA256.BGI file }
grsys := InstallUserDriver('SVGA256', @DetectVGA256);
{$ENDIF}
grsys := detect;
grmode := 0;
initgraph (grsys,grmode,BGIDIR);
if graphresult < 0 then begin
writeln (grapherrormsg(grsys));
writeln;
writeln ('If the .BGI files are not in the current directory');
writeln ('then you can use SET to set an environment variable');
writeln ('called BGIDIR which points to the .BGI file directory.');
writeln;
writeln ('SurfModl Halted');
halt(1);
end;
{Write the menu options}
restorecrtmode;
clrscr;
writeln;
writeln ('Choose from the following system types:');
for Sys := 1 to MAXSYS do
if (Sys_name[lglsys[sys]] <> 'RESERVED') then
writeln (Lglsys[Sys]:3,' ',Sys_name[Lglsys[Sys]]);
repeat
write ('System Number [Hit Enter to use default of ',grsys,']: ');
readln (message);
if message = '' then
str (grsys,message);
val(message,num,code);
until ((code = 0) and (trunc(num) in [1..MAXSYS]) and
(SYS_NAME[lglsys[num]] <> 'RESERVED'));
grsys := trunc(num);
{Get mode for this driver}
clrscr;
getmoderange(grsys,modelow,modehi);
if modelow <> modehi then begin {Select the graphics mode}
writeln ('Choose from the following graphics modes:');
Case grsys of
CGA : begin
writeln (' 0: 320x200, Lightgreen Lightred, Yellow');
writeln (' 1: 320x200, LightCyan, LightMagenta, White');
writeln (' 2: 320x200, Green, Red, Brown');
writeln (' 3: 320x200, Cyan, Magenta, Lightgrey');
writeln (' 4: 640x200, one colour');
end;
MCGA: Begin
writeln (' 0: 320x200, Lightgreen Lightred, Yellow');
writeln (' 1: 320x200, LightCyan, LightMagenta, White');
writeln (' 2: 320x200, Green, Red, Brown');
writeln (' 3: 320x200, Cyan, Magenta, Lightgrey');
writeln (' 4: 640x200, one colour');
writeln (' 5: 640x480, one colour');
end;
EGA : Begin
writeln (' 0: 640x200, 16 Colour');
writeln (' 1: 640x350, 16 Colour');
end;
EGA64: Begin
writeln (' 0: 640x200, 16 Colour');
writeln (' 1: 640x350, 4 Colour');
end;
EGAMONO: Begin
writeln (' 3: 640x350, 1 Colour');
end;
HercMONO: Begin
writeln (' 0: 720x348, 1 Colour');
end;
ATT400: Begin
writeln (' 0: 320x200, Lightgreen Lightred, Yellow');
writeln (' 1: 320x200, LightCyan, LightMagenta, White');
writeln (' 2: 320x200, Green, Red, Brown');
writeln (' 3: 320x200, Cyan, Magenta, Lightgrey');
writeln (' 4: 640x200, one colour');
writeln (' 5: 640x400, one colour');
end;
VGA: Begin
writeln (' 0: 640x200, 16 Colour');
writeln (' 1: 640x350, 16 Colour');
writeln (' 2: 640x480, 16 Colour');
end;
PC3270: Begin
writeln (' 0: 720x350, 1 Colour');
end;
(* KVC 04/20/91 - Removed support for IBM 8514
IBM8514: Begin
writeln (' 0: 640x850, 256 Colour');
writeln (' 1: 1024x768 256 Colour');
end;
*)
VGA256: Begin
writeln (' 0: Standard VGA (320x200, 256 Colour)');
writeln (' 1: Super VGA 256k (640x400, 256 Colour)');
{ Not all VGA's can display all modes, because some don't have
enough memory:
}
if modehi >= 2 then
writeln (' 2: Super VGA 512k (640x480, 256 Colour)');
if modehi >= 3 then
writeln (' 3: Super VGA 512k (800x600, 256 Colour)');
if modehi >= 4 then
writeln (' 4: Super VGA 1024k (1024x768, 256 Colour)');
end;
{$IFDEF VAXMATE} {DEC VAXMATE modes}
VM400 : begin
writeln (' 0: 320x200, Lightgreen Lightred, Yellow');
writeln (' 1: 320x200, LightCyan, LightMagenta, White');
writeln (' 2: 320x200, Green, Red, Brown');
writeln (' 3: 320x200, Cyan, Magenta, Lightgrey');
writeln (' 4: 640x200, one colour');
writeln (' 5: 640x400, four colour');
writeln (' 6: 640x400, one colour');
end;
{$ENDIF}
end; {case}
grmode := modehi;
repeat
write ('Enter Graphic Mode [',grmode,']: ');
readln (message);
if message = '' then
str (grmode,message);
val(message,num,code);
until ((code = 0) and (trunc(num) in [modelow..modehi]));
grmode := trunc(num);
end; { if modelow <> modehi }
end; { procedure SELECT_SYS }
function CHECKEY: boolean;
{ Return TRUE if the 'A' key has been pressed, or FALSE otherwise }
var c: char;
begin
c := ' ';
if (keypressed) then begin
c := readkey;
if (upcase (c) = 'A') then
Checkey := TRUE
else
Checkey := FALSE;
end else
Checkey := FALSE;
end; { function CHECKEY }
{ GRAFSTAT and STOPSTAT control the plotting of "status dots" at the bottom
of the graphics screen. STOPSTAT clears the line away and also
reinitializes the local (static) variables.
}
var Statpos: integer; { next X-position to plot a status dot }
procedure STOPSTAT;
var c: char;
begin
{$IFDEF USE_IFF}
if Grsys <> IFF then begin
{$ENDIF}
Statpos := Gxmin+3;
gdraw (Gxmin+1, Gymax-1, Gxmax-1, Gymax-1, 0);
{$IFDEF USE_IFF}
end;
{$ENDIF}
{ Clear out the console input buffer }
while (keypressed) do
c := readkey;
end; { procedure STOPSTAT }
function GRAFSTAT: boolean;
{ Every call to GRAFSTAT produces a new status dot, and also
checks the keyboard for a run abort. GRAFSTAT returns TRUE if the
user wishes to abort the run (by pressing the 'A' key), or FALSE otherwise.
}
begin
{$IFDEF USE_IFF}
if Grsys <> IFF then begin
{$ENDIF}
Statpos := Statpos + 1;
if (Statpos > Gxmax-3) then
stopstat;
gplot (Statpos, Gymax-1, 1);
{$IFDEF USE_IFF}
end;
{$ENDIF}
Grafstat := checkey;
end; { procedure GRAFSTAT }
procedure SETGMODE (Nmatl: integer);
{ Set up graphics mode and draw the window }
var
message: string;
temp : integer;
begin
setgraphmode(grmode);
temp := (graphresult);
message := grapherrormsg(temp);
if message <> 'No error' then begin
restorecrtmode;
writeln;
writeln ('SETGraphMODE: BGI error: ',message);
writeln ('Error number: ',temp);
writeln ('GrSys is: ',Grsys);
writeln ('GrMode is: ',Grmode);
writeln ('SurfModl Halted');
halt;
end else begin
RGB_levels := 1;
if grsys = VGA256 then
RGB_levels := 63
{$ifdef USE_IFF}
else if grsys = IFF then
RGB_levels := 255
{$endif}
;
if Nmatl > 0 then
def_palette (Nmatl);
gdraw (Gxmin, Gymin, Gxmax, Gymin, 1);
gdraw (Gxmax, Gymin, Gxmax, Gymax, 1);
gdraw (Gxmax, Gymax, Gxmin, Gymax, 1);
gdraw (Gxmin, Gymax, Gxmin, Gymin, 1);
stopstat; { Initialize the graphics status line }
if ngraphchar < length (Flpurpose) then
flpurpose := copy (Flpurpose,1,ngraphchar);
if ShowTitle then
puttext ((ngraphchar - length(Flpurpose)) * 4, 10, Flpurpose, Graphcol);
end; {else}
end; { procedure SETGMODE }
function savescrn (filename : string) : boolean;
{ Save the current graphics screen image to disk.
KVC 8/31/91 Modified to save screens larger than 64K
}
var
imagefile : file;
bitmap : pointer;
success : boolean;
nbytes : longint;
nbytes_alloc : longint;
xmax, ymax : integer;
y1, y2 : integer;
nbytes_line : longint;
nlines : longint;
{$IFDEF DEBUG}
tot_nbytes : longint;
{$ENDIF}
begin
success := true;
{ First we find out how many bytes in one line of the screen, since the
full screen may require more than 64K bytes and we can't allocate that
much all at once.
}
xmax := GetMaxX;
ymax := GetMaxY;
if (Grsys = VGA256) then
{ Bug in SVGA256 doesn't set imagesize correctly }
nbytes_line := xmax + 5
else
nbytes_line := imagesize (0, 0, xmax, 0);
{$IFDEF DEBUG}
tot_nbytes := 0;
{$ENDIF}
{ Find out how many lines we can fit in a 64K buffer. Note that this
is a conservative estimate, since in fact there is a 4-byte header
included in every imagesize calculation (and therefore every
getimage/putimage too). The actual number of lines we can fit in a
64K buffer is larger than this, but we'll settle for the small loss
of speed to avoid making any assumptions about the header.
}
if (nbytes_line * (ymax+1) > MAXALLOC) then
nlines := MAXALLOC div nbytes_line
else
nlines := ymax + 1;
{ Allocate storage }
nbytes_alloc := nlines * nbytes_line;
getmem (bitmap, nbytes_alloc);
if bitmap = nil then {error}
success := false
else begin
{$I-}
assign (imagefile,filename);
if ioresult <> 0 then
success := false;
rewrite (imagefile,1);
if ioresult <> 0 then
success := false;
y1 := 0;
y2 := nlines - 1;
{ Write the graphics adapter type & mode first: }
blockwrite (imagefile,grsys,sizeof(grsys));
if ioresult <> 0 then
success := false;
blockwrite (imagefile,grmode,sizeof(grmode));
if ioresult <> 0 then
success := false;
if (grsys = VGA256) then begin
{ Have to save the VGA palette too }
blockwrite (imagefile, VGApal, sizeof(VGApal));
if ioresult <> 0 then
success := false;
end;
while (success) and (y1 <= y2) do begin
if (Grsys = VGA256) then
{ Bug in SVGA256 doesn't set imagesize correctly }
nbytes := (xmax+1) * (y2-y1+1) + 4
else
nbytes := imagesize (0, y1, xmax, y2);
if (nbytes > nbytes_alloc) then
{ Whoops, we didn't get enough storage }
success := false
else begin
{$IFDEF DEBUG}
tot_nbytes := tot_nbytes + nbytes;
{$ENDIF}
getimage (0, y1, xmax, y2, bitmap^);
if (graphresult = GrOK) AND (bitmap <> nil) then begin
{ Show what we just got in reverse video }
putimage (0, y1, bitmap^, NOTput);
if (graphresult <> GrOK) then
success := false
else
blockwrite (imagefile, bitmap^, nbytes);
if ioresult <> 0 then
success := false;
y1 := y1 + nlines;
y2 := y2 + nlines;
if (y2 > ymax) then
y2 := ymax;
{ Put it back in normal video }
putimage (0, y1 - nlines, bitmap^, NormalPut);
end else
success := false;
end; { if nbytes > nbytes_alloc }
end; { while }
close (imagefile);
if ioresult <> 0 then
success := false;
{$I+}
release (bitmap);
end; { if bitmap = nil }
savescrn := success;
end; {savescrn}
{$ifdef NEVER}
KVC Removed readscrn from SURFGRAF.PAS because we don't want all
the extra baggage associated with XMS to be carried with SURFMODL:
function readscrn (filename : string; var grsys,grmode : integer;
var image : picbuf; var nbuf : integer; var nlines_buf : nlpic;
var vgapalette : SurfPalette; oldgrsys, oldgrmode : integer) : boolean;
var
imagefile : file;
success : boolean;
nbytes : longint;
tmp : real;
xmax : integer;
ymax : integer;
nbytes_line : longint;
y1, y2 : integer;
grtmp : integer;
grmtmp : integer;
begin
success := true;
{$I-}
assign (imagefile,filename);
if ioresult <> 0 then begin
success := false;
writeln ('File "',filename,'" not found');
end;
reset (imagefile,1);
if ioresult <> 0 then begin
success := false;
writeln ('File "',filename,'" not found');
end;
blockread (imagefile,grsys,sizeof(grsys));
if ioresult <> 0 then begin
success := false;
writeln ('Could not read grsys');
end;
blockread (imagefile,grmode,sizeof(grmode));
if ioresult <> 0 then begin
success := false;
writeln ('Could not read grmode');
end;
if (grsys = VGA256) then begin
{ Have to restore the VGA palette too }
blockread (imagefile, vgapalette, sizeof(vgapalette));
if ioresult <> 0 then begin
success := false;
writeln ('Could not read VGA palette');
end;
end;
{$I+}
if success then begin
{ Have to go into graphics mode to read line size }
if (grsys <> oldgrsys) then begin
if (oldgrsys <> -1) then
{ Not the first time, exit graphics mode first }
closegraph;
{$IFNDEF EXTERNAL}
{ KVC 04/20/91 Make Turbo recognize the SVGA256.BGI file }
grtmp := InstallUserDriver('SVGA256', @DetectVGA256);
{$ENDIF}
{ KVC 09/11/91 This call to detect shouldn't be necessary, but otherwise
Turbo does not seem to be using the SVGA256.BGI file.
}
grtmp := detect;
grmtmp := 0;
if (grsys <> VGA256) then
grtmp := grsys;
initgraph (grtmp,grmtmp,BGIDIR);
if (grsys = VGA256) then
{ Set the palette }
VGASetAllPalette (vgapalette);
end else if (grmode <> oldgrmode) then
setgraphmode (grmode);
xmax := GetMaxX;
ymax := GetMaxY;
if (Grsys = VGA256) then
{ Bug in SVGA256 doesn't set imagesize correctly }
nbytes_line := xmax + 5
else
nbytes_line := imagesize (0, 0, xmax, 0);
{ Find out how many lines we can fit in a 64K buffer }
if (nbytes_line * (ymax+1) > MAXALLOC) then
nlines_buf[1] := MAXALLOC div nbytes_line
else
nlines_buf[1] := ymax + 1;
y1 := 0;
y2 := nlines_buf[1] - 1;
nbuf := 0;
{ The following loop is done once per buffer }
while (success) and (y1 <= y2) do begin
{ Make sure we don't allocate more than we need }
nbuf := nbuf + 1;
nlines_buf[nbuf] := y2 - y1 + 1;
if (Grsys = VGA256) then
{ Bug in SVGA256 doesn't set imagesize correctly }
nbytes := (xmax+1) * (y2-y1+1) + 4
else
nbytes := imagesize (0, y1, xmax, y2);
getmem (image[nbuf], nbytes);
if (image[nbuf] = nil) then begin
success := false;
writeln ('Could not allocate memory for bitmap');
end else begin {memory successfully allocated}
{$I-}
blockread (imagefile, image[nbuf]^, nbytes);
if ioresult <> 0 then begin
success := false;
writeln ('Could not read image');
end;
{$I+}
end; {Memory allocated}
y1 := y1 + nlines_buf[nbuf];
y2 := y2 + nlines_buf[nbuf];
if (y2 > ymax) then
y2 := ymax;
end; { while }
end; { Image successfully read }
{$I-}
close (imagefile);
{$I+}
if ioresult <> 0 then
success := false;
readscrn := success;
end; {readscrn}
{$endif}
{************************************************************************}
function get_env
(env_var: String) { environment variable to look for }
: String; { Value of environment variable }
{ }
{ Description: }
{ Returns the value associated with the given environment variable }
{ }
{************************************************************************}
{ }
{ Revision History: }
{ "a" means Alpha version, Not Completed }
{ "b" means Beta Test Version, Completed but in testing }
{ "c" means Completed Version. This version is now frozen }
{ }
{************************************************************************}
var
i,j: integer;
result: String;
found: boolean;
table_address: integer;
begin { get_environment }
result := '';
i := 0;
table_address := memW[PrefixSeg:$002c];
if length (env_var) <> 0 then begin
for j := 1 to length(env_var) do begin {convert to uppercase}
if env_var[j] in ['a'..'z'] then begin
env_var[j] := chr(ord(env_var[j])-32);
end; {then}
end; {for}
repeat
result := '';
while (mem[table_address:i]) <> 0 do begin
result := result + chr(mem[table_address:i]);
i := i + 1;
end;
if pos (env_var,result) = 1 then begin
found := true;
result := copy (result,length(env_var) + 2,length(result));
end
else
found := false;
i := i + 1;
until found or (result = '');
end; { Then find value }
get_env := result;
end; {get_env}
{ VGASetAllPalette: Set the VGA graphics palette while in 256-color mode.
This procedure courtesy of Borland, as supplied with their VGA256
package.
}
procedure VGASetAllPalette(var P : SurfPalette);
var
Regs : Registers;
begin
with Regs do
begin
AX := $1012;
BX := 0;
CX := 256;
ES := Seg(P);
DX := Ofs(P);
end;
Intr($10, Regs);
end; { VGASetAllPalette }
{ DetectVGA256: This is the routine used when installing the VGA256
driver for use of VGA 256-color mode.
}
{$F+}
function DetectVGA256 : integer;
var
DetectedDriver : integer;
SuggestedMode : integer;
begin
DetectGraph(DetectedDriver, SuggestedMode);
if (DetectedDriver = VGA) or (DetectedDriver = MCGA) then
DetectVGA256 := 0 { Default video mode = 0 }
else
DetectVGA256 := grError; { Couldn't detect hardware }
end; { DetectVGA256 }
{$F-}
{ KVC 11/09/91 The following function causes getmem() to return a NIL
when out of heap space, instead of making the program crash on Error 203.
Thanks to Gisbert Selke for pointing out how to do this.
}
{$F+}
function HeapErrorTrap (size: word): integer;
begin
HeapErrorTrap := 1; { Forces new() and getmem() to return NIL }
end;
{$F-}
{The following procedures link in the appropriate .OBJ files so the graphics }
{drivers are always memory resident. If you get an error message, then you }
{must copy the .BGI files into this directory, then run the BGI2OBJ batch }
{file. It uses the turbo pascal 4.0 utility BINOBJ. }
{$IFDEF LINKATT}
{$DEFINE LINKING}
procedure ATTDriver; external;
{$L ATT.OBJ }
{$ENDIF}
{$IFDEF LINKCGA}
{$DEFINE LINKING}
procedure CgaDriver; external;
{$L CGA.OBJ }
{$ENDIF}
{$IFDEF LINKEGAVGA}
{$DEFINE LINKING}
procedure EgaVgaDriver; external;
{$L EGAVGA.OBJ }
{$ENDIF}
{$IFDEF LINKHERC}
{$DEFINE LINKING}
procedure HercDriver; external;
{$L HERC.OBJ }
{$ENDIF}
{$IFDEF LINKPC3270}
{$DEFINE LINKING}
procedure PC3270Driver; external;
{$L PC3270.OBJ }
{$ENDIF}
{$IFDEF LINKVGA256}
{$DEFINE LINKING}
{$L VGA256.OBJ }
{$ENDIF}
procedure Abort(Msg : string);
begin
Writeln(Msg, ': ', GraphErrorMsg(GraphResult));
Halt(1);
end;
{ Following is the initialization procedure for the SURFGRAF unit. It
is automatically invoked when the program starts up.
}
BEGIN
driveron := false;
DoRandom := false;
RandShade := 1.0 / 16.0;
Mono := false; { Dithering on by default }
grsys := -1;
grmode := -1;
viewchanged := true;
{Get the directory the .BGI drivers are in}
BGIDIR := get_env('BGIDIR');
{ Force getmem to return NIL on out of heap space: }
HeapError := @HeapErrorTrap;
{$IFDEF LINKCGA}
if RegisterBGIdriver(@CGADriver) < 0 then
Abort('CGA');
{$ENDIF}
{$IFDEF LINKEGAVGA}
if RegisterBGIdriver(@EGAVGADriver) < 0 then
Abort('EGA/VGA');
{$ENDIF}
{$IFDEF LINKHERC}
if RegisterBGIdriver(@HercDriver) < 0 then
Abort('Herc');
{$ENDIF}
{$IFDEF LINKATT}
if RegisterBGIdriver(@ATTDriver) < 0 then
Abort('AT&T');
{$ENDIF}
{$IFDEF LINKPC2370}
if RegisterBGIdriver(@PC3270Driver) < 0 then
Abort('PC 3270');
{$ENDIF}
{ Don't need to register the VGA256 driver because it was already done. }
{vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv}
{If you get an error message, "Error 15: File not found (xxx.OBJ)" then you }
{must copy the .BGI files into this directory, then run the BGI2OBJ batch }
{file. It uses the turbo pascal 4.0 utility BINOBJ so it must be available }
{^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^}
END.